package com.quanyan.weichat.protocol.pay_protocol;


import com.quanyan.common.utils.DateUtils;
import com.quanyan.weichat.common.Configure;
import com.quanyan.weichat.common.RandomStringGenerator;
import com.quanyan.weichat.common.Signature;

import java.util.Date;

/**
 * Created by zijun.song on 2015/9/11.
 * https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1
 */
public class AppPayData {

    private String appid; //公众账号iD

    private String mch_id; //商户号

    private String nonce_str; //保证签名不可预测。调用随机数函数生成，将得到的值转换为字符串。

    private String sign; //签名, 算法详见 http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3

    private String body; //商品简要描述

    private String detail; //商品名称明细列表

    private String attach; //附加数据;查询api和支付通知中会原样返回.

    private String out_trade_no; //商户系统内部订单号. length <= 32

    private String fee_type;//币种   CNY

    private int total_fee; //订单总额. 单位 分.

    private String spbill_create_ip; //用户IP.

    private String time_start; //订单生成时间.

    private String time_expire; //订单失效时间

    private String goods_tag; //商品标记

    private String notify_url; //接收微信异步支付通知回调地址.(必须是公网)

    private String trade_type; //交易类型: JSAPI / NATIVE APP WAP

    private String product_id; //商户自定义商品ID


    public AppPayData(Builder builder) {
        setAppid(builder.configure.getAppID());
        setMch_id(builder.configure.getMchID());
        setFee_type("CNY");
        setTrade_type("APP");
        setNotify_url(builder.configure.getNotify_url());
        setBody(builder.body);//要支付的商品的描述信息，用户会在支付成功页面里看到这个信息
        setDetail(builder.detail);
        setAttach(builder.attach);//支付订单里面可以填的附加数据，API会将提交的这个附加数据原样返回，有助于商户自己可以注明该笔消费的具体内容，方便后续的运营和记录
        setOut_trade_no(builder.out_trade_no);//商户系统内部的订单号,32个字符内可包含字母, 确保在商户系统唯一
        setTotal_fee(builder.total_fee); //订单总金额，单位为“分”，只能整数
        setSpbill_create_ip(builder.spbill_create_ip); //APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP。

        Date startDate = new Date();
        Date endDate = DateUtils.addTime(startDate, builder.payTimeOutSeconds, DateUtils.TIME_TYPE_SECOND);
        String time_start = DateUtils.getTimeStringYYYYMMDDHHMMSS(startDate);
        String time_expire = DateUtils.getTimeStringYYYYMMDDHHMMSS(endDate);

        setTime_start(time_start);//订单生成时间， 格式为yyyyMMddHHmmss，如2009年12 月25 日9 点10 分10 秒表示为20091225091010。时区为GMT+8 beijing。该时间取自商户服务器
        setTime_expire(time_expire); //订单失效时间，格式同上
        // setGoods_tag(goods_tag);//商品标记，微信平台配置的商品标记，用于优惠券或者满减使用

        setProduct_id(builder.product_id);
        setNonce_str(RandomStringGenerator.getRandomStringByLength(32));//随机字符串，不长于32 位
        String sign = null; //根据API给的签名规则进行签名
        try {
            sign = Signature.getSign(this, builder.configure.getKey());
            setSign(sign);//把签名数据设置到Sign这个属性中
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    public String getAppid() {
        return appid;
    }

    public void setAppid(String appid) {
        this.appid = appid;
    }

    public String getMch_id() {
        return mch_id;
    }

    public void setMch_id(String mch_id) {
        this.mch_id = mch_id;
    }

    public String getNonce_str() {
        return nonce_str;
    }

    public void setNonce_str(String nonce_str) {
        this.nonce_str = nonce_str;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getBody() {
        return body;
    }

    public void setBody(String body) {
        this.body = body;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail;
    }

    public String getAttach() {
        return attach;
    }

    public void setAttach(String attach) {
        this.attach = attach;
    }

    public String getOut_trade_no() {
        return out_trade_no;
    }

    public void setOut_trade_no(String out_trade_no) {
        this.out_trade_no = out_trade_no;
    }

    public String getFee_type() {
        return fee_type;
    }

    public void setFee_type(String fee_type) {
        this.fee_type = fee_type;
    }

    public int getTotal_fee() {
        return total_fee;
    }

    public void setTotal_fee(int total_fee) {
        this.total_fee = total_fee;
    }

    public String getSpbill_create_ip() {
        return spbill_create_ip;
    }

    public void setSpbill_create_ip(String spbill_create_ip) {
        this.spbill_create_ip = spbill_create_ip;
    }

    public String getTime_start() {
        return time_start;
    }

    public void setTime_start(String time_start) {
        this.time_start = time_start;
    }

    public String getTime_expire() {
        return time_expire;
    }

    public void setTime_expire(String time_expire) {
        this.time_expire = time_expire;
    }

    public String getGoods_tag() {
        return goods_tag;
    }

    public void setGoods_tag(String goods_tag) {
        this.goods_tag = goods_tag;
    }

    public String getNotify_url() {
        return notify_url;
    }

    public void setNotify_url(String notify_url) {
        this.notify_url = notify_url;
    }

    public String getTrade_type() {
        return trade_type;
    }

    public void setTrade_type(String trade_type) {
        this.trade_type = trade_type;
    }

    public String getProduct_id() {
        return product_id;
    }

    public void setProduct_id(String product_id) {
        this.product_id = product_id;
    }

    public static class Builder {
        String body;
        String detail;
        String attach;
        String out_trade_no;
        int total_fee;
        int payTimeOutSeconds;
        String spbill_create_ip;
        String product_id;
        Configure configure;

        public Builder setBody(String body) {
            this.body = body;
            return this;
        }

        public Builder setDetail(String detail) {
            this.detail = detail;
            return this;
        }

        public Builder setAttach(String attach) {
            this.attach = attach;
            return this;
        }

        public Builder setOut_trade_no(String out_trade_no) {
            this.out_trade_no = out_trade_no;
            return this;
        }

        public Builder setTotal_fee(int total_fee) {
            this.total_fee = total_fee;
            return this;
        }

        public Builder setSpbill_create_ip(String spbill_create_ip) {
            this.spbill_create_ip = spbill_create_ip;
            return this;
        }

        public Builder setProduct_id(String product_id) {
            this.product_id = product_id;
            return this;
        }

        public Builder setConfigure(Configure configure) {
            this.configure = configure;
            return this;
        }

        public Builder setPayTimeOutSeconds(int payTimeOutSeconds) {
            this.payTimeOutSeconds = payTimeOutSeconds;
            return this;
        }

        public AppPayData build() {
            return new AppPayData(this);
        }
    }

    @Override
    public String toString() {
        return "{" +
                "\"appid\":'" + appid + '\'' +
                ", \"mch_id\":'" + mch_id + '\'' +
                ", \"nonce_str\":'" + nonce_str + '\'' +
                ", \"sign\":'" + sign + '\'' +
                ", \"body\":'" + body + '\'' +
                ", \"detail\":'" + detail + '\'' +
                ", \"attach\":'" + attach + '\'' +
                ", \"out_trade_no\":'" + out_trade_no + '\'' +
                ", \"fee_type\":'" + fee_type + '\'' +
                ", \"total_fee\":" + total_fee +
                ", \"spbill_create_ip\":'" + spbill_create_ip + '\'' +
                ", \"time_start\":'" + time_start + '\'' +
                ", \"time_expire\":'" + time_expire + '\'' +
                ", \"goods_tag\":'" + goods_tag + '\'' +
                ", \"notify_url\":'" + notify_url + '\'' +
                ", \"trade_type\":'" + trade_type + '\'' +
                ", \"product_id\":'" + product_id + '\'' +
                '}';
    }
}
